home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifndef mac
- #include <time.h>
- #endif
- #include <math.h>
- #include <signal.h>
-
- #include "config.h"
- #include "lint.h"
- #include "nlhack.h"
- #include "comm.h"
- #include "lang.h"
- #include "interpret.h"
- #include "wiz_list.h"
- #include "exec.h"
- #include "object.h"
- #include "rc.h"
-
- #ifdef mac
- #include "mac.h"
-
- struct tm *localtime(const time_t *timer);
- char *asctime (const struct tm *timeptr);
- #endif
-
- #ifdef DIRENT
- #include <dirent.h>
- #define namlen(de) strlen((de)->d_name)
- #define direct dirent
- #else
- #include <sys/dir.h>
- #define namlen(de) (de)->d_namlen
- #endif
-
- #ifdef MARK
- #include <prof.h>
- #endif
-
- #ifdef MARK
- #define CASE(x) case x: MARK(x);
- #else
- #define CASE(x) case x:
- #endif
-
- extern struct { unsigned counter, size; } sbrk_stat;
- extern struct object *master_ob;
- extern int num_player;
- extern struct interactive **all_players;
-
- extern int fstat PROT((int, struct stat *));
- extern int stat PROT((char *, struct stat *));
-
- extern void push_vector PROT((struct vector *));
- extern void push_svalue PROT((struct svalue *));
- extern void pop_n_elems PROT((int));
- extern int do_move PROT((char *, char *));
- extern struct variable *find_status PROT((char *, int));
- extern int get_line_number_if_any PROT((void));
- extern void show_info_about PROT((char *, char *, struct interactive *));
-
- static struct vector *explode_file PROT((struct object *, char *));
- static int copy_file PROT((char *, char *));
- static int tail PROT((char *, int));
- static char *make_printable PROT((char *));
- static struct vector *list_files PROT((char *, char *, struct object *));
- static void full_name PROT((char *, int));
- static void fetch_type PROT((char *, char *, int));
- static int pstrcmp PROT((char **, char **));
- static int rename_file PROT((char *, char*));
- static int sroot PROT((int));
- static struct svalue *get_var PROT((char *));
- static int set_var PROT((char *, struct svalue *));
- static void grep PROT ((char *, struct vector *));
- static int write_file PROT((struct object *, char *, char *));
- static void people PROT((void));
- static void kick_me PROT((int));
- static int planet_shout PROT((struct object *, char *));
- static int match_illegal PROT((char *));
- static void set_hard_invis PROT((struct object *, int));
- static void set_see_hinvis PROT((struct object *, int));
-
- void init_nlhack()
- {
- #ifdef _AIX
- signal(SIGUSR1, kick_me);
- #endif
- }
-
- static void kick_me(sig)
- int sig;
- {
- #ifndef mac
- signal(SIGUSR1, kick_me);
- #endif
- }
-
- int nlhack(instruction, pc, fp, sp, num_arg)
- int instruction, num_arg;
- char *pc;
- struct svalue *fp, *sp;
- {
- int ret;
- struct svalue *sval_ret;
-
- switch(instruction) {
- default:
- return 0;
- CASE(F_GET_MEM_USAGE);
- push_number(sbrk_stat.size);
- break;
- CASE(F_EXPLODE_FILE);
- {
- struct vector *v;
- v = explode_file(current_object, sp->u.string);
- pop_n_elems(1);
- if (v) {
- push_vector(v);
- v->ref--;
- }
- else {
- push_number(0);
- }
- break;
- }
- CASE(F_COPY_FILE);
- ret = copy_file((sp-1)->u.string, sp->u.string);
- pop_n_elems(2);
- push_number(ret);
- break;
- CASE(F_TAIL);
- if ((num_arg == 2 &&
- ((sp-1)->type != T_NUMBER || sp->type != T_STRING)) ||
- (num_arg == 1 && sp->type != T_STRING)) {
- error("Bad type argument(s) to tail()\n");
- }
- if (num_arg == 2)
- ret = tail(sp->u.string, (sp-1)->u.number);
- else
- ret = tail(sp->u.string, 20);
- pop_n_elems(num_arg);
- push_number(ret);
- break;
- CASE(F_LS);
- {
- struct vector *v;
-
- if (num_arg == 2)
- v = list_files((sp-1)->u.string, sp->u.string, current_object);
- else
- v = list_files(sp->u.string,0, current_object);
- pop_n_elems(num_arg);
- if (v) {
- push_vector(v);
- v->ref--;
- }
- else {
- push_number(0);
- }
- break;
- }
- CASE(F_RENAME_FILE);
- ret = rename_file((sp-1)->u.string, sp->u.string);
- pop_n_elems(2);
- push_number(ret);
- break;
- CASE(F_SQRT);
- ret = sroot(sp->u.number);
- pop_n_elems(1);
- push_number(ret);
- break;
- CASE(F_GET_VAR);
- sval_ret = get_var(sp->u.string);
- pop_n_elems(1);
- if (sval_ret)
- push_svalue(sval_ret);
- else
- push_number(0);
- break;
- CASE(F_SET_VAR);
- ret = set_var((sp-1)->u.string, sp);
- pop_n_elems(2);
- push_number(ret);
- break;
- CASE(F_GREP);
- grep((sp-1)->u.string, sp->u.vec);
- pop_n_elems(2);
- push_number(0);
- break;
- CASE(F_WRITE_FILE);
- ret = write_file(current_object, (sp-1)->u.string, sp->u.string);
- pop_n_elems(2);
- push_number(ret);
- break;
- CASE(F_PEOPLE);
- people();
- break;
- CASE(F_PLANET_SHOUT);
- ret = planet_shout((sp-1)->u.ob, sp->u.string);
- pop_n_elems(2);
- push_number(ret);
- break;
- CASE(F_SET_HARD_INVIS);
- set_hard_invis((sp-1)->u.ob, sp->u.number);
- pop_n_elems(2);
- push_number(0);
- break;
- CASE(F_SET_SEE_HINVIS);
- set_see_hinvis((sp-1)->u.ob, sp->u.number);
- pop_n_elems(2);
- push_number(0);
- break;
- }
- return 1;
- }
-
- static struct vector *explode_file(ob, fname)
- char *fname;
- struct object *ob;
- {
- char line[1000], what[100];
- struct vector *ret;
- FILE *f;
- int lines = 0, i = 0;
-
- if (!fname)
- return 0;
- if (fname[0] == '/') fname++;
- #ifdef COMPAT_MODE
- if (ob->user) {
- if (strncmp(fname, "players/", 8) != 0 ||
- strncmp(fname+8, ob->user->name, strlen(ob->user->name)) != 0 ||
- !legal_path(fname))
- {
- error("Illegal use of explode_file(%s)\n", fname);
- return 0;
- }
- } else if ((strncmp(ob->name, "obj/", 4) != 0 &&
- strncmp(ob->name, "room/", 5) != 0) ||
- !legal_path(fname)) {
- error("Illegal use of explode_file(%s)\n", fname);
- return 0;
- }
- if (ob != master_ob && sscanf(fname, "log/admin/%s", what) == 1)
- return 0;
- #else
- fname = check_valid_path(fname, ob->eff_user, "explode_file", 0);
- if (!fname)
- return 0;
- #endif
- f = fopen(fname, "r");
- if (f == 0)
- return 0;
- while (fgets(line, sizeof line, f) != 0)
- lines++;
- if (lines == 0)
- {
- fclose(f);
- return 0;
- }
- if (lines > MAX_EXPLODE_FILE_LINES) lines = MAX_EXPLODE_FILE_LINES;
- ret = allocate_array(lines);
- rewind(f);
- while (i != lines && fgets(line, sizeof line, f) != 0)
- {
- if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = '\0';
- ret->item[i].type = T_STRING;
- ret->item[i].string_type = STRING_MALLOC;
- ret->item[i].u.string = string_copy(line);
- i++;
- }
- fclose(f);
- return ret;
- }
-
- static int copy_file(source, dest)
- char *source, *dest;
- {
- char src[512], *dst;
- char line[1000];
- FILE *sf, *df;
-
- #ifdef COMPAT_MODE
- if (command_giver->name != current_object->name)
- {
- /*
- * Security patch.
- */
- add_message("Illegal use of copy_file.\n");
- return 0;
- }
- source = check_file_name(source , 0);
- #else
- source = check_valid_path(source, current_object->eff_user, "copy_file", 0);
- #endif
- if (source == 0)
- return 0;
- /*
- * The next part is necessary, because the return string of check_file_name
- * might be deallocated at the next "apply" (which is called from
- * check_file_name itself, used again below).
- */
- strncpy(src, source, sizeof src);
- src[sizeof src - 1] = '\0';
- #ifdef COMPAT_MODE
- dst = check_file_name(dest, 1);
- #else
- dst = check_valid_path(dest, current_object->eff_user, "copy_file", 1);
- #endif
- if (dst == 0)
- return 0;
- sf = fopen(src, "r");
- if (sf == 0)
- return 0;
- #if defined(LOG_OPEN) && defined(COMPAT_MODE)
- if (strncmp(dst, "open/", 5) == 0) {
- FILE *fp;
- fp = fopen("log/admin/OPEN", "a");
- if (fp != NULL) {
- fprintf(fp, "\"%s\" by %s\n",
- dst,
- command_giver->living_name);
- fclose(fp);
- }
- }
- #endif
- df = fopen(dst, "w");
- if (df == 0)
- {
- fclose(sf);
- return 0;
- }
- while (fgets(line, sizeof line, sf) != 0)
- fputs(line, df);
- fclose(sf);
- fclose(df);
- return 1;
- }
-
- static int tail(path, start)
- char *path;
- int start;
- {
- char buff[1000];
- FILE *f;
- struct stat st;
- int offset;
-
- if (start < 1) return 0;
- if (start > 5 * MAX_LINES) start = 5 * MAX_LINES;
- #ifdef COMPAT_MODE
- path = check_file_name(path, 0);
- #else
- path = check_valid_path(path, current_object->eff_user, "tail", 0);
- #endif
- if (path == 0)
- return 0;
- f = fopen(path, "r");
- if (f == 0)
- return 0;
- if (fstat(fileno(f), &st) == -1)
- fatal("Could not stat an open file.\n");
- offset = st.st_size - 80 * start;
- if (offset < 0)
- offset = 0;
- if (fseek(f, offset, 0) == -1)
- fatal("Could not seek.\n");
- /* Throw away the first incomplete line. */
- if (offset > 0)
- (void)fgets(buff, sizeof buff, f);
- while(fgets(buff, sizeof buff, f)) {
- add_message("%s", make_printable(buff));
- }
- fclose(f);
- return 1;
- }
-
- static char *make_printable(s)
- register char *s;
- {
- static char buff[2000];
- register char *p;
-
- p = buff;
- while (*s) {
- if (*s < ' ' && *s != '\t' && *s != '\n') {
- *p++ = '^';
- *p++ = '@' + (*s & 0x2f);
- } else {
- *p++ = *s;
- }
- s++;
- }
- *p = '\0';
- return buff;
- }
-
- static void full_name(name, n)
- char name[];
- int n;
- {
- int i;
- if (strlen(name) < n)
- for (i = strlen(name); i < n; i++) name[i] = ' ';
- name[n] = '\0';
- }
-
- static void fetch_type(path, file, L_opt)
- char path[], file[];
- int L_opt;
- {
- char temp[100];
- struct stat st;
-
- (void)strcpy(temp, path);
- (void)strcat(temp, "/");
- (void)strcat(temp, file);
- if (stat(temp, &st) == -1) return;
- if (S_ISDIR(st.st_mode)) (void)strcat(file, "/");
- else {
- if (file[strlen(file)-1] == 'c' && file[strlen(file)-2] == '.') {
- if (L_opt) {
- if (find_object2(temp))
- strcat(file, "@");
- }
- else {
- (void)strcat(file, "*");
- }
- }
- }
- }
-
- static int pstrcmp(p1, p2)
- char **p1, **p2;
- {
- return strcmp(*p1, *p2);
- }
-
- static int rename_file(fr, t)
- char *fr, *t;
- {
- char from[512], *to;
- struct stat st;
-
- #ifdef COMPAT_MODE
- if (command_giver->name != current_object->name)
- {
- /*
- * Security patch.
- */
- add_message("Illegal use of rename_file.\n");
- return 0;
- }
- fr = check_file_name(fr, 1);
- #else
- fr = check_valid_path(fr, current_object->eff_user, "rename_file", 1);
- #endif
- if (fr == 0)
- return 0;
- strncpy(from, fr, sizeof from);
- from[sizeof from - 1] = '\0';
- #ifdef COMPAT_MODE
- to = check_file_name(t, 1);
- #else
- to = check_valid_path(t, current_object->eff_user, "rename_file", 1);
- #endif
- if (to == 0)
- return 0;
- #ifdef LOG_OPEN
- if (strncmp(to, "open/", 5) == 0) {
- FILE *fp;
- fp = fopen("log/admin/OPEN", "a");
- if (fp != NULL) {
- fprintf(fp, "\"%s\" by %s\n",
- to,
- command_giver->living_name);
- fclose(fp);
- }
- }
- #endif
- /*
- * This now calls do_move from simulate.c, which handles cross-filesystem
- * moves.
- */
- if (stat(from, &st) < 0)
- return 0;
- return !do_move(from, to);
- }
-
- static int sroot(n)
- int n;
- {
- return n < 0 ? -1 : (int) sqrt((double) n);
- }
-
- static struct svalue *get_var(str)
- char *str;
- {
- struct variable *p;
-
- p = find_status(str, 0);
- if (!p)
- return 0;
- return ¤t_object->variables[p - current_object->prog->variable_names];
- }
-
- static int set_var(str, arg1)
- char *str;
- struct svalue *arg1;
- {
- struct variable *p;
-
- p = find_status(str, 0);
- if (!p)
- return 0;
- assign_svalue(
- ¤t_object->variables[p - current_object->prog->variable_names],
- arg1);
- return 1;
- }
-
- static void grep(str, files)
- char *str;
- struct vector *files;
- {
- char temp[500], command[750], line[1000], *t;
- int i, a, nr_lines = 0, nr_files = 0;
- struct stat st;
- FILE *f;
-
- if (!str || !(files->size) || files->item[0].type != T_STRING)
- return;
- if (current_object != command_giver)
- {
- add_message("Illegal use of grep()\n");
- return;
- }
- for (i = 0; i < files->size; i++)
- if (files->item[i].type == T_STRING)
- {
- #ifdef COMPAT_MODE
- t = check_file_name(files->item[i].u.string, 0);
- #else
- t = check_valid_path(files->item[i].u.string,
- current_object->eff_user,"grep", 0);
- #endif
- if (t && stat(t, &st) != -1)
- {
- if (st.st_size <= GREP_FILE_SIZE)
- {
- (void)strcpy(temp, t);
- nr_files++;
- break;
- }
- else
- add_message("%s : Too big.\n", t);
- }
- }
- if (!nr_files)
- {
- add_message("No or illegal file(s)!\n");
- return;
- }
- for (a = i+1; a < files->size; a++)
- {
- if (nr_files >= MAX_GREP_SIZE)
- {
- add_message("Too many grep files! Working on %d files now.\n", MAX_GREP_SIZE);
- break;
- }
- if (files->item[a].type == T_STRING)
- {
- t = check_file_name(files->item[a].u.string, 0);
- if (t && stat(t, &st) != -1)
- {
- if (st.st_size <= GREP_FILE_SIZE)
- {
- (void)strcat(temp, " ");
- (void)strcat(temp, t);
- nr_files++;
- }
- else
- add_message("%s : Too big.\n", t);
- }
- }
- else
- error("Corrupted file-array!\n");
- }
- (void)sprintf(command, "fgrep -n %s %s > %s", str, temp, GREP_FILE);
- (void)system(command);
- f = fopen(GREP_FILE, "r");
- if (!f)
- {
- add_message("No match.\n");
- return;
- }
- while(fgets(line, sizeof line, f) != 0)
- {
- add_message("%s", line);
- nr_lines++;
- if (nr_lines > MAX_LINES)
- {
- add_message("**TRUNCATED**\n");
- break;
- }
- }
- fclose(f);
- unlink(GREP_FILE);
- }
-
- static int write_file(ob, file, str)
- char *file;
- char *str;
- struct object *ob;
- {
- FILE *f;
- char what[100];
-
- if (!file)
- return 0;
- if (file[0] == '/') file++;
- #ifdef COMPAT_MODE
- if (ob->user) {
- if (strncmp(file, "players/", 8) != 0 ||
- strncmp(file+8, ob->user->name, strlen(ob->user->name)) != 0 ||
- !legal_path(file)) {
- error("Illegal write_file(%s)\n", file);
- }
- } else if ((strncmp(current_object->name, "obj/", 4) != 0 &&
- strncmp(current_object->name, "room/", 5) != 0 &&
- strncmp(current_object->name, "std/", 4) != 0) ||
- !legal_path(file)) {
- error("Illegal use of write_file()\n");
- }
- if (sscanf(file, "users/%s", what) == 1)
- if (!strchr(what, '/')) error("Illegal use of write_file()\n");
- if (sscanf(file, "obj/%s", what) == 1)
- error("Illegal use of write_file()\n");
- #else
- file = check_valid_path(file, current_object->eff_user, "write_file", 1);
- #endif
- f = fopen(file, "a");
- if (f == 0)
- return 0;
- fwrite(str, strlen(str), 1, f);
- fclose(f);
- return 1;
- }
-
- struct vector *users() {
- static struct object **tmp_arr = 0;
- int i, vis, n, invis;
- struct vector *ret;
-
- if (!tmp_arr)
- tmp_arr = (struct object **)
- xalloc(MAX_PLAYERS * sizeof (struct object *));
- invis = !command_giver || !(command_giver->flags & O_CAN_SEE_HINVIS);
- for (i = 0, n = num_player, vis = 0; n; i++) {
- if (all_players[i]) {
- n--;
- if (!(invis && (all_players[i]->ob->flags & O_HARD_INVIS)))
- tmp_arr[vis++] = all_players[i]->ob;
- }
- }
- ret = allocate_array(vis);
- for (i = 0; i < vis; i++) {
- ret->item[i].type = T_OBJECT;
- ret->item[i].u.ob = tmp_arr[i];
- add_ref(tmp_arr[i], "users");
- }
- return ret;
- }
-
- /* Returns an array of all objects contained in 'ob'
- */
- struct vector *all_inventory(ob)
- struct object *ob;
- {
- struct vector *d;
- struct object *cur;
- int cnt, invis;
-
- invis = !command_giver || !(command_giver->flags & O_CAN_SEE_HINVIS);
- for (cnt=0, cur=ob->contains; cur; cur = cur->next_inv) {
- if (invis && (cur->flags & O_HARD_INVIS))
- continue;
- else
- cnt++;
- }
- if (!cnt)
- return allocate_array(0);
-
- d = allocate_array(cnt);
- for (cnt=0, cur=ob->contains; cur; cur = cur->next_inv) {
- if (invis && (cur->flags & O_HARD_INVIS))
- continue;
- d->item[cnt].type=T_OBJECT;
- d->item[cnt].u.ob = cur;
- add_ref(cur,"all_inventory");
- cnt++;
- }
- return d;
- }
-
- static void people()
- {
- struct object *ob;
- struct svalue *player;
- int n, i, invis;
-
- invis = !command_giver || !(command_giver->flags & O_CAN_SEE_HINVIS);
- for (i = 0, n = num_player; n; i++) {
- if (!all_players[i])
- continue;
- n--;
- ob = all_players[i]->ob;
- if (invis && (ob->flags & O_HARD_INVIS))
- continue;
- player = apply("query_name", ob, 0);
- if (player == 0 || player->type != T_STRING)
- continue;
- if (!ob->super)
- continue;
- show_info_about(player->u.string, ob->super->name, ob->interactive);
- }
- }
-
- void set_eff_user(new_ob)
- struct object *new_ob;
- {
- /*
- * Dirty hack made a lot dirtier: since I did not want to add another
- * field to the object struct, I abused the eff_user field, which is not
- * used in COMPAT_MODE. This hack is _incompatible_ with 'native' mode.
- * - Zappa
- */
- if (current_object) {
- if (current_object->interactive && current_object->living_name) {
- new_ob->eff_user = (struct wiz_list *)
- make_shared_string(current_object->living_name);
- } else {
- new_ob->eff_user = current_object->eff_user;
- }
- }
- else {
- new_ob->eff_user = 0;
- }
- }
-
- /*
- * List files in a directory. The standard 'ls' could be used, but
- * it takes too much time.
- * Prepared for flag decoding.
- *
- * Look at the the last component of the path name. It is a regular
- * expression, select only matching files.
- *
- * All .i files are only listed if they match the regexp.
- */
- static struct vector *list_files(path, flags, ob)
- char *path, *flags;
- struct object *ob;
- {
- char buff[160]; /* Will never need more than two lines */
- int i, max, lines, num, j, truncated = 0, pos;
- DIR *dirp;
- struct direct *de;
- char **names, name_buffer[MAX_LINES * 80];
- struct stat st;
- char regexp[80], *p, path2[100], temp[100], temp2[10];
- int do_match = 0, all = 0, long_list = 0, f_opt = 0, to_array = 0;
- int L_opt = 0;
- struct vector *ret;
-
- if (!path)
- path = ".";
- #ifdef COMPAT_MODE
- path = check_file_name(path, 0);
- #else
- path = check_valid_path(path, current_object->eff_user, "ls", 0);
- #endif
- if (path == 0)
- return 0;
- if (flags)
- {
- for (i=0; i < strlen(flags); i++)
- if (flags[i] != 'a' && flags[i] != 'l' &&
- flags[i] != 'F' && flags[i] != '@' &&
- flags[i] != 'L') return 0;
- if (strchr(flags, 'a')) all = 1;
- if (strchr(flags, 'l')) long_list = 1;
- if (strchr(flags, 'F')) f_opt = 1;
- if (strchr(flags, '@')) to_array = 1;
- if (strchr(flags, 'L')) L_opt = 1;
- }
- if (to_array) /* to maintain security */
- {
- if (ob->user) {
- if (strncmp(path, "players/", 8) != 0 ||
- strncmp(path+8, ob->user->name, strlen(ob->user->name)) != 0 ||
- !legal_path(path))
- {
- error("Illegal use of ls(%s)\n", path);
- return 0;
- }
- } else if ((strncmp(current_object->name, "obj/", 4) != 0 &&
- strncmp(current_object->name, "room/", 5) != 0 &&
- strncmp(current_object->name, "std/", 4) != 0) ||
- !legal_path(path)) {
- error("Illegal use of ls()\n");
- return 0;
- }
- }
- strncpy(path2, path, sizeof path2);
- path2[sizeof path2 - 1] = '\0';
- p = path2 + strlen(path2) - 2;
- if (p >= path2 && p[0] == '/' && p[1] == '.')
- p[0] = '\0';
- if (stat(path2, &st) == -1) {
- /* Either the directory does not exist, or it is a regexp
- * file name. Strip of the last component.
- */
- p = strrchr(path2, '/');
- if (p == 0 || p[1] == '\0')
- return 0;
- strncpy(regexp, p+1, sizeof regexp);
- regexp[sizeof regexp - 1] = '\0';
- *p = '\0';
- do_match = 1;
- }
- dirp = opendir(path2);
- if (dirp == 0) {
- add_message("No such directory '%s'\n", path2);
- return 0;
- }
- pos = 0;
- max = 0;
- num = 0;
- /*
- * First step, find the number of file names.
- */
- for(de = readdir(dirp); de; de = readdir(dirp)) {
- if (!do_match && de->d_name[namlen(de)-1] == 'i' &&
- de->d_name[namlen(de)-2] == '.')
- continue;
- if ((strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0))
- continue;
- if (do_match && !match_string(regexp, de->d_name))
- continue;
- if (!all && (!do_match || strcmp(regexp, "*") == 0)
- && de->d_name[0] == '.')
- continue;
- if (namlen(de) + pos >= sizeof name_buffer) {
- truncated = 1;
- break;
- }
- if (namlen(de) > max)
- max = namlen(de) + 1;
- pos += namlen(de) + 1;
- num++;
- }
- if (num == 0)
- {
- closedir(dirp);
- return 0;
- }
- max++;
- /*
- * Copy all file names into a name space, and set up pointer
- * into it.
- */
- names = (char **)alloca(num * sizeof (char *));
- rewinddir(dirp);
- for(pos=0, i=0, de = readdir(dirp); i < num; de = readdir(dirp)) {
- if (!do_match && de->d_name[namlen(de)-1] == 'i' &&
- de->d_name[namlen(de)-2] == '.')
- continue;
- if ((strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0))
- continue;
- if (do_match && !match_string(regexp, de->d_name))
- continue;
- if (!all && (!do_match || strcmp(regexp, "*") == 0)
- && de->d_name[0] == '.')
- continue;
- names[i] = name_buffer + pos;
- if (f_opt || L_opt)
- {
- (void)strcpy(temp, de->d_name);
- fetch_type(path2, temp, L_opt);
- strcpy(name_buffer + pos, temp);
- pos += strlen(temp) + 1;
- }
- else
- {
- strcpy(name_buffer + pos, de->d_name);
- pos += namlen(de) + 1;
- }
- i++;
- }
- /* Sort the names. */
- qsort((char *)names, num, sizeof (char *), pstrcmp);
- /*
- * Print the file names in nice columns, as many as possible
- * on every line. That means that there can be one extra name
- * on each line, depending on the size of the last name on the line.
- */
- if (!long_list)
- {
- if (to_array)
- /*
- * got to determine array-size
- */
- {
- for(lines=0, i=0, j=0; j<num; j++) {
- if (i * max + strlen(names[j]) >= 79) {
- i = 0;
- lines++;
- if (lines > MAX_LINES) break;
- }
- i++;
- }
- ret = allocate_array(lines+1);
- }
- for(lines=0, i=0, j=0; j<num; j++) {
- if (i * max + strlen(names[j]) >= 79) {
- /*
- * Strip the last spaces on the last name to ensure that
- * it will fit last on the line.
- */
- for (i=strlen(buff) - 1; buff[i] == ' '; i--)
- buff[i] = '\0';
- if (!to_array)
- add_message("%s\n", buff);
- else
- {
- (void) strcpy(temp, buff);
- ret->item[lines].type = T_STRING;
- ret->item[lines].string_type = STRING_MALLOC;
- ret->item[lines].u.string = string_copy(strcat(temp, "\n"));
- }
- i = 0;
- lines++;
- if (lines > MAX_LINES) {
- truncated = 1;
- break;
- }
- }
- sprintf(buff + i * max, "%-*s", max, names[j]);
- i++;
- }
- if (i)
- {
- if (!to_array)
- add_message("%s\n", buff);
- else
- {
- (void) strcpy(temp, buff);
- ret->item[lines].type = T_STRING;
- ret->item[lines].string_type = STRING_MALLOC;
- ret->item[lines].u.string = string_copy(strcat(temp, "\n"));
- lines++;
- }
- }
- }
- else
- {
- char owner[15];
-
- if (to_array)
- if (num <= MAX_LINES)
- ret = allocate_array(num);
- else
- ret = allocate_array(MAX_LINES + 2);
- if (sscanf(path2, "players/%s", owner) != 1)
- {
- if (sscanf(path2, "open/%s", owner) != 0)
- (void)strcpy(owner, "open\0");
- else
- (void)strcpy(owner, "system\0");
- }
- else
- {
- p = strchr(owner, '/');
- if (p) *p = '\0';
- }
- full_name(owner, 12);
- (void)strcat(path2, "/");
- for(lines=0, j=0; j<num; j++) {
- int len;
-
- (void)strcpy(temp, path2);
- (void)strcat(temp, names[j]);
- if (L_opt || f_opt) {
- len = strlen(temp) - 1;
- if (strchr("*@/", temp[len]))
- temp[len] = '\0';
- }
- if (stat(temp, &st) == -1) continue;
- (void)strcpy(temp, names[j]);
- full_name(temp, 20);
- (void)strcat(temp,"----> ");
- if (S_ISDIR(st.st_mode))
- (void)strcat(temp, "Directory\t");
- else
- (void)strcat(temp, "File\t\t");
- sprintf(temp2, "%d", st.st_size);
- (void)strcat(temp, temp2);
- (void)strcat(temp, "\t");
- (void)strcat(temp, owner);
- #ifdef NOSTRFTIME
- strcpy(buff, asctime(localtime(&(st.st_mtime))) + 4);
- buff[12] = '\0';
- #else
- strftime(buff, 100, "%h %d %H:%M", localtime(&(st.st_mtime)));
- #endif
- (void)strcat(temp, buff);
- if (!to_array)
- add_message("%s\n", temp);
- else
- {
- (void) strcpy(buff, temp);
- ret->item[lines].type = T_STRING;
- ret->item[lines].string_type = STRING_MALLOC;
- ret->item[lines].u.string = string_copy(strcat(buff, "\n"));
- }
- lines++;
- if (lines > MAX_LINES) {
- truncated = 1;
- break;
- }
- }
- }
- if (truncated)
- if (!to_array)
- add_message("***TRUNCATED***\n");
- else {
- ret->item[lines].type = T_STRING;
- ret->item[lines].string_type = STRING_MALLOC;
- ret->item[lines].u.string = string_copy("***TRUNCATED***\n");
- }
- closedir(dirp);
- return (to_array) ? ret : 0;
- }
-
- static int planet_shout(planet, mess)
- struct object *planet;
- char *mess;
- {
- struct object *ob, *save_command_giver = command_giver;
- char *p;
- struct svalue *muffled, *cur_planet;
- int nr = 0, i, n;
-
- for (p=mess; *p; p++) {
- if ((*p < ' ' || *p > '~') && *p != '\n')
- *p = ' ';
- }
- p = 0;
- /*
- * This should be in simul_efun.c..
- */
- for (i = 0, n = num_player; n; i++)
- {
- if (!all_players[i])
- continue;
- n--;
- ob = all_players[i]->ob;
- if (ob == save_command_giver)
- continue;
- muffled = apply("query_muffled", ob, 0);
- if (muffled && muffled->type == T_NUMBER && muffled->u.number == 1)
- continue;
- cur_planet = apply("query_planet_obj", ob, 0);
- if (!cur_planet || cur_planet->type != T_OBJECT ||
- cur_planet->u.ob != planet)
- continue;
- nr++;
- command_giver = ob;
- add_message("%s", mess);
- }
- command_giver = save_command_giver;
- return nr;
- }
-
- void log_sbrk(size)
- unsigned size;
- {
- int lineno;
-
- lineno = get_line_number_if_any();
- if (current_object) {
- printf("sbrk(%d) object: '%s'", size, current_object->name);
- if (lineno)
- printf(", program: '%s' line %d\n", current_prog->name, lineno);
- else
- putchar('\n');
- }
- }
-
- char **log_admin_files;
- int nr_log_admin_files;
-
- int log_admin_check(file)
- char *file;
- {
- int i;
-
- for (i = 0; i < nr_log_admin_files; i++)
- if (!strcmp(file, log_admin_files[i]))
- return 1;
- return 0;
- }
-
- int remove_file(path)
- char *path;
- {
- DIR *dirp;
- struct direct *de;
- struct stat st;
- char rgexp[100], *p, path2[200], temp[200];
- int do_match = 0, danger = 0, found = 0, interactive;
-
- #ifdef COMPAT_MODE
- path = check_file_name(path, 1);
- #else
- path = check_valid_path(path, current_object->eff_user, "remove_file", 1);
- #endif
-
- if (path == 0)
- return 0;
- /*
- * Wildcards may only be used from player.c
- */
- interactive = (command_giver && command_giver == current_object);
- strncpy(path2, path, sizeof path2);
- path2[sizeof path2 - 1] = '\0';
- p = path2 + strlen(path2) - 2;
- if (p >= path2 && p[0] == '/' && p[1] == '.')
- p[0] = '\0';
- if (stat(path2, &st) == -1) {
- /* Either the directory does not exist, or it is a regexp
- * file name. Strip of the last component.
- */
- p = strrchr(path2, '/');
- if (p == 0 || p[1] == '\0')
- return 0;
- strncpy(rgexp, p+1, sizeof rgexp);
- rgexp[sizeof rgexp - 1] = '\0';
- *p = '\0';
- do_match = 1;
- }
- if (do_match && interactive)
- {
- dirp = opendir(path2);
- if (dirp == 0) {
- add_message("No such directory '%s'\n", path2);
- return 0;
- }
- (void)strcat(path2, "/");
- if (strcmp(path2, "obj/") == 0) danger = 1;
- for(de = readdir(dirp); de; de = readdir(dirp)) {
- if (!match_string(rgexp, de->d_name))
- continue;
- if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
- continue;
- if (strcmp(rgexp, "*") == 0 && de->d_name[0] == '.')
- continue;
- found = 1;
- if (danger && match_illegal(de->d_name))
- {
- add_message("Failed to remove: %s\n", de->d_name);
- continue;
- }
- (void)strcpy(temp, path2);
- (void)strcat(temp, de->d_name);
- (void)strcat(temp, "\0");
- if (unlink(temp) == -1)
- add_message("Failed to remove: %s\n", temp);
- }
- if (!found) add_message("File(s) not found.\n");
- closedir(dirp);
- }
- else
- {
- if (unlink(path) == -1) {
- if (interactive) {
- add_message("No such file: %s\n", path);
- return 0;
- }
- }
- }
- return 1;
- }
-
- static int match_illegal(file)
- char *file;
- {
- /*
- * No write permission for these files
- */
- if (strcmp(file, "player.c") == 0 ||
- strcmp(file, "living.c") == 0 ||
- strcmp(file, "living.h") == 0 ||
- strcmp(file, "creature.c") == 0 ||
- strcmp(file, "creature.h") == 0) return 1;
- return 0;
- }
-
- int all_cap(str)
- char *str;
- {
- int i;
- for (i = 0; i < strlen(str); str++, i++)
- if (*str < 'A' || *str > 'Z') return 0;
- return 1;
- }
-
- static void set_hard_invis(ob, n)
- struct object *ob;
- int n;
- {
- if (ob != current_object || current_object != command_giver
- || !(ob->flags & O_ONCE_INTERACTIVE))
- error("Illegal use of set_hard_invis()\n");
- if (n)
- ob->flags |= O_HARD_INVIS;
- else
- ob->flags &= ~O_HARD_INVIS;
- }
-
- static void set_see_hinvis(ob, n)
- struct object *ob;
- int n;
- {
- if (ob != current_object || current_object != command_giver
- || !(ob->flags & O_ONCE_INTERACTIVE))
- error("Illegal use of set_see_hinvis()\n");
- if (n)
- ob->flags |= O_CAN_SEE_HINVIS;
- else
- ob->flags &= ~O_CAN_SEE_HINVIS;
- }
-